<template>
  <div class="canvas-area">
    <canvas ref="bg" style="width: 400px; height: 225px;"></canvas>
    <canvas ref="defects" class='defects'></canvas>
  </div>
  <input type="range" :min="min" max="20" v-model="label" @change="invalid"/> {{label}}
  <br/>
  
  <br/>
  <img ref='imgEl' style="width: 400px; position: fixed; left: -400px;">
</template>

<script setup lang="ts">
import {ref, reactive, defineComponent, computed, defineProps, onMounted, nextTick, defineEmits } from 'vue'
import img from '../../assets/nanshengzhi.jpg'
const defaultX = Math.floor(Math.random() * 300) + 60
const defaultY = Math.floor(Math.random() * 164) + 20
console.log(defaultX,-(Math.floor((defaultX / 400) * 100)))
const bg = ref()
const imgEl = ref()
const defects = ref()
const imgWidth = 20
const label = ref(-(100 - Math.floor((defaultX / 400) * 100)))
const min = label.value
const props = defineProps({
  imgUrl: {
    type: String,
    default: img
  }
})
const emit = defineEmits(['validated'])


onMounted(() => {
  imgEl.value.src = props.imgUrl
  nextTick(async() => {
    const imgres = await imgOnload()
    drawBg(imgres)
    drawDefects(imgres, 20, 20)
    let flag = true
    defects.value.onmousemove = (e) => {
      if(flag){
        flag = false
        let x = e.clientX;
        let y = e.clientY;
        // console.log(x, y);
        drawDefects(imgres, x, y)
        setTimeout(() => {
          flag = true
        }, 10)
      }
    }
  })
})
/**
 * @description 绘制背景图片
 */
const drawBg = (imgres: HTMLElement & {naturalWidth?: number, naturalHeight?: number}) => {
  const bgCanvas = bg.value?.getContext('2d')
  bg.value.width = 400
  bg.value.height = 225
  bgCanvas.drawImage(imgres, 0, 0, imgres.naturalWidth, imgres.naturalHeight, 0, 0, 400, 225)
  bgCanvas.save() // 保存上下文
  bgCanvas.arc(defaultX, defaultY, imgWidth, 3 * Math.PI, -.5 * Math.PI) //左上
  bgCanvas.arc(defaultX + imgWidth, defaultY, imgWidth, 1.5 * Math.PI, 2 * Math.PI)  //右上
  bgCanvas.arc(defaultX + imgWidth, defaultY + 20, imgWidth, 2 * Math.PI, 0.5 * Math.PI) //右下
  bgCanvas.arc(defaultX, defaultY + 20, imgWidth, 0.5 * Math.PI, 1 * Math.PI) //左下
  bgCanvas.lineTo(defaultX - 20, defaultY)
  bgCanvas.stroke()
  bgCanvas.clip() //剪切
  bgCanvas.strokeStyle = "rgba(0,0,0,0.5)"
  bgCanvas.fillStyle = "rgba(0,0,0,0.5)"
  bgCanvas.fill()
  bgCanvas.restore()
}

/**
 * @description 绘制剪切图片
 * 
 */
const drawDefects = (imgres: HTMLElement & {naturalWidth?: number, naturalHeight?: number}, x: number, y: number) => {
  const defectsCanvas = defects.value?.getContext('2d')
  defects.value.width = 400
  defects.value.height = 225
  const _defaultX = x
  const _defaultY = y
  const xtox = (x) / 400 * imgres.naturalWidth
  const ytoy = (y) / 255 * imgres.naturalHeight
  defectsCanvas.save() // 保存上下文
  // defectsCanvas.arc(_defaultX, _defaultY, imgWidth, 3 * Math.PI, -.5 * Math.PI) //左上
  // defectsCanvas.arc(_defaultX + imgWidth, _defaultY, imgWidth, 1.5 * Math.PI, 2 * Math.PI)  //右上
  // defectsCanvas.arc(_defaultX + imgWidth, _defaultY + 20, imgWidth, 2 * Math.PI, 0.5 * Math.PI) //右下
  // defectsCanvas.arc(_defaultX, _defaultY + 20, imgWidth, 0.5 * Math.PI, 1 * Math.PI) //左下
  // defectsCanvas.lineTo(_defaultX - 20, _defaultY)
  defectsCanvas.arc(defaultX, defaultY, imgWidth, 3 * Math.PI, -.5 * Math.PI) //左上
  defectsCanvas.arc(defaultX + imgWidth, defaultY, imgWidth, 1.5 * Math.PI, 2 * Math.PI)  //右上
  defectsCanvas.arc(defaultX + imgWidth, defaultY + 20, imgWidth, 2 * Math.PI, 0.5 * Math.PI) //右下
  defectsCanvas.arc(defaultX, defaultY + 20, imgWidth, 0.5 * Math.PI, 1 * Math.PI) //左下
  defectsCanvas.lineTo(defaultX - 20, defaultY)
  defectsCanvas.stroke()
  defectsCanvas.strokeStyle = "rgba(0,0,0,0.5)"
  defectsCanvas.fillStyle = "rgba(0,0,0,0.5)"
  defectsCanvas.fill()
  defectsCanvas.clip() //剪切
  console.log(x, y);
  defectsCanvas.drawImage(
    imgres, 
    0, 
    0, 
    imgres.naturalWidth, 
    imgres.naturalHeight, 
    0, 
    0, 
    400, 
    255
  )
  defectsCanvas.restore()
}
const imgOnload = async ():Promise<HTMLElement> => {
  return new Promise((reslove) => {
    imgEl.value.onload = (e: any) => {
      reslove(imgEl.value)
    }
  })
}


const invalid = () => {
  console.log(label.value)
  emit('validated', label.value == 0)
}
</script>

<style lang='less' scoped>
button{
  width: 100%;
  margin: 20px 0;
}
.content{
  display: flex;
  .preView{
    flex: 1;
  }
  .editArea{
    width: 500px;
  }
}
.canvas-area{
  display: block;
  position: relative;
  .defects{
    display: block;
    position: absolute;
    top: 0;
    cursor: pointer;
  }
}
</style>
